import HeroUtils from "@/mota/utils/HeroUtils";
import { ImageName } from "@/mota/data/ImageLoader";
import { BattleInfo, GetEnemyInfo } from "@/mota/data/BattleDataUtils";
import { MotaInterface } from "@/mota";
import { GetItemEmit, getItemMap, HeroAttribute, heroAttributeMap, ParseUnit, useItemMap } from "@/mota/data/ItemDataUnit";

export type AttackResult = undefined | "unable" | "fail" | number;

export default class AttributeUtils implements HeroAttribute, MotaInterface {

	public hero: HeroUtils;

	/** 血量[1000] */
	public hp: number = 9999;
	/** 攻击[10] */
	public attack: number = 9999;
	/** 防御[10] */
	public defence: number = 9999;
	/** 金币[0] */
	public gold: number = 9999;
	/** 经验[0] */
	public exp: number = 9999;
	/** 黄钥匙[0] */
	public keyYellow: number = 99;
	/** 红钥匙[0] */
	public keyRed: number = 99;
	/** 蓝钥匙[0] */
	public keyBlue: number = 99;
	/** 绿钥匙[0] */
	public keyGreen: number = 0;
	/** 铁门钥匙[0] */
	public keyIron: number = 99;

	public ZIndex: number = 1;

	public constructor(hero: HeroUtils) {
		this.hero = hero;
	}

	/**
	 * 决斗
	 * @param enemyName 战斗对象
	 */
	public Battle(enemyName: ImageName): boolean {
		const { hero: { Mota: { tip } } } = this;
		const attackRes = this.AttackCalc(enemyName);
		if (attackRes === undefined) {
			tip.AddIconMessage(enemyName, "非可战斗单位");
		} else if (attackRes === "unable") {
			tip.AddIconMessage(enemyName, "无法战胜");
		} else if (attackRes === "fail") {
			tip.AddIconMessage(enemyName, "战斗失败");
		} else {
			const enemy = <BattleInfo>GetEnemyInfo(enemyName);
			let [, , , , gold, exp] = enemy;
			tip.AddIconMessage(enemyName, `战斗胜利，增加${this.AddAttribute([["gold", gold], ["exp", exp]])}`);
		}
		return typeof attackRes === "number";
	}

	/**
	 * 计算战斗结果
	 * @param enemyName 战斗对象
	 */
	public AttackCalc(enemyName: ImageName): AttackResult {
		const { hero: { Mota: { tip } } } = this;
		const enemy: BattleInfo | undefined = GetEnemyInfo(enemyName);
		if (enemy === undefined) {
			tip.AddIconMessage(enemyName, "非可战斗单位");
			return undefined;
		}
		let [, enemy_hp, enemy_attack, enemy_defence] = enemy;
		if (this.attack < enemy_defence) {
			return "unable";
		} else if (enemy_attack < this.defence) {
			return 0;
		}
		let me_attack = true;
		const hp = this.hp;
		let me_hp_reduce = 0;
		while (hp + me_hp_reduce > 0) {
			if (me_attack) {
				enemy_hp -= this.attack - enemy_defence;
				if (enemy_hp <= 0) {
					return me_hp_reduce;
				}
			} else {
				me_hp_reduce -= enemy_attack - this.defence;
			}
			me_attack = !me_attack;
		}
		return "fail";
	}

	public AddAttribute(infoList: GetItemEmit[]): string {
		const attrs: string[] = [];
		for (const [attr, count] of infoList) {
			const [, name, unit] = heroAttributeMap[attr];
			attrs.push(ParseUnit(name, count, unit, false));
			this[attr] += count;
		}
		return attrs.join("、");
	}

	public ReduceAttribute(infoList: GetItemEmit[]): string | undefined {
		const lackList: string[] = [];
		for (const [attr, count] of infoList) {
			if (this[attr] < count) {
				const [, name, unit] = heroAttributeMap[attr];
				lackList.push(ParseUnit(name, count - this[attr], unit, false));
			}
		}
		if (lackList.length > 0) {
			return lackList.join("、");
		}
		for (const [attr, value] of infoList) {
			this[attr] -= value;
		}
		return undefined;
	}

	public Draw: MotaInterface["Draw"] = (draw) => {
		const { _2d } = draw;
		const { hero: { Mota: { onBuild } } } = this;

		draw.DrawBackground(["石地板", [0, 0, 3, 10]]);
		if (onBuild) { return; }

		_2d.save();
		_2d.fillStyle = "#FFFFFF";
		draw.SetFont(800, 1 / 2, "Mota");
		_2d.textAlign = "right";

		draw.DrawImage("血量", true, 0, [0.25, 0.5, 1, 1]);
		draw.fillText(this.hp.toString(), 3.5, 1.2);

		draw.translate(0, 1.75);
		draw.DrawImage("神圣剑", true, 0, [0.25, 0.5, 1, 1]);
		draw.fillText(this.attack.toString(), 3.5, 1.2);

		draw.translate(0, 1.75);
		draw.DrawImage("神圣盾", true, 0, [0.25, 0.5, 1, 1]);
		draw.fillText(this.defence.toString(), 3.5, 1.2);

		draw.translate(0, 1.75);
		draw.DrawImage("幸运金币", true, 0, [0.25, 0.5, 1, 1]);
		draw.fillText(this.gold.toString(), 3.5, 1.2);

		draw.translate(0, 1.75);
		draw.DrawImage("经验卷轴", true, 0, [0.25, 0.5, 1, 1]);
		draw.fillText(this.exp.toString(), 3.5, 1.2);

		draw.translate(0, 1.6);
		draw.DrawImage("黄钥匙", true, 0, [0.25, 0.5, 1, 1]);
		_2d.fillStyle = "#FFCCAA";
		draw.fillText(this.keyYellow.toString().padStart(2, "0"), 1.7, 1.3);

		_2d.save();
		draw.translate(0, 0.8);
		draw.DrawImage("红钥匙", true, 0, [0.25, 0.5, 1, 1]);
		_2d.fillStyle = "#FF8888";
		draw.fillText(this.keyRed.toString().padStart(2, "0"), 1.7, 1.3);
		_2d.restore();

		draw.translate(1.8, 0);
		draw.DrawImage("蓝钥匙", true, 0, [0.25, 0.5, 1, 1]);
		_2d.fillStyle = "#CCCCFF";
		draw.fillText(this.keyBlue.toString().padStart(2, "0"), 1.7, 1.3);

		draw.translate(0, 0.8);
		draw.DrawImage("铁门钥匙", true, 0, [0.25, 0.5, 1, 1]);
		_2d.fillStyle = "#D2DDCE";
		draw.fillText(this.keyIron.toString().padStart(2, "0"), 1.7, 1.3);

		_2d.restore();
	}
}
